home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Subject: v07i015: my_wgetstr(); wgetstr() with line editing
- Reply-To: mott@ucscb.UCSC.EDU (Hung H. Le)
-
- Posting-number: Volume 7, Issue 15
- Submitted-by: mott@ucscb.UCSC.EDU (Hung H. Le)
- Archive-name: my_wgetstr
-
- my_wgetstr() is equipvalent to wgetstr() in "curses" but
- with line editing feature. Will recognize erase, kill and
- control-w as editing characters.
- ------------------------------------------------------------
- Hung H. Le
- mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott
- mott@ucscd.BITNET #include <std_disclaimer>
- ------------------------------------------------------------
-
- --- Include shar file --
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # example.c
- # makefile
- # my_wgetstr.c
- # my_wgetstr.h
- # This archive created: Sun May 21 10:46:51 1989
- # By: Hung H. Le (Uncle Charlie Summer Camp)
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(1427 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'README'
- X
- X I wrote my_wgetstr() as a replacement for wgets() in curses.
- X
- XWhat my_getstr() does that wgets() does not?
- X . line editing as in csh. Erase char, kill char, control-w
- X are recognized.
- X . check for overflow. Two possible actions can be taken
- X 1. returns immediately
- X 2. bell() to let user know that buffer is full
- X only newline and editing chars are passed through at
- X this point
- X
- XWhat my_getstr() does not do that wgets() does?
- X . does not check for illegal scrolling.
- X
- XHeader file:
- X remember to include "my_wgetstr.h"
- X my_getstr(), RET and NO_RET are defined in there.
- X
- XUsage:
- X n = my_wgetstr(WINDOW *win, char *str, int size, int ret);
- X win: the concerned window
- X str: storage for input chars
- X size: my_wgetstr() will get at most (size - 1) chars.
- X ret: what to do when buffer is full
- X 0: bell()
- X 1: returns
- X you can use NO_RET or RET
- X n: number of characters actually gets
- X
- X my_getstr(char *str, int size, int ret);
- X is a macro defined as
- X#define my_getstr(str, size) my_wgetstr(stdscr, str, size)
- X in "my_wgetstr.h"
- X
- Xmy_wgetstr() returns if
- X . input is a newline
- X . if ( (strlen(str) == (size - 1)) and (ret) )
- X
- Xmy_wgetstr() DOES NOT check for illegal scrolling so it is the
- Xprogrammer's job to take care of that.
- X
- XAfter unpack this package. Type "make" to make "example".
- XTry out "example".
- X
- Xwritten by Hung Le
- Xmott@ucscb.ucsc.edu
- X...!ucbvax!ucscc!ucscb!mott
- X
- X This code is placed in Public Domain.
- X
- SHAR_EOF
- if test 1427 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 1427 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'example.c'" '(2271 characters)'
- if test -f 'example.c'
- then
- echo shar: will not over-write existing file "'example.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'example.c'
- X/*
- X * Example program --
- X * A possible replacement for curses' wgetstr(). Allows
- X * limited editing. Recognizes the erase and kill chars.
- X *
- X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott)
- X * History:
- X * 01/18/89 - Initial version
- X * 03/20/89 - add control-w to delete word
- X *
- X * Release to Public Domain
- X */
- X
- X#include <curses.h>
- X#include <signal.h>
- X/* REMEMBER to include "my_wgetstr.h" */
- X#include "my_wgetstr.h"
- X
- X/* test my_wgetstr() */
- Xmain()
- X{
- X char buffer[30];
- X static char *header[] =
- X {
- X "INPUT WINDOW",
- X "Look Ma ... Line editing in curses",
- X "Erase char to erase, Kill char to delete the whole line",
- X "control-w to delete a word, empty input line to quit",
- X };
- X char ender[81], *name, *getlogin(), *getenv();
- X int clean_up(), n;
- X int x_pos, y_pos;
- X WINDOW *inwin;
- X
- X initscr();
- X clear();
- X refresh();
- X
- X /* set up interupt handler */
- X signal(SIGINT, clean_up);
- X
- X /* set up input window */
- X inwin = newwin(8, COLS, 3, 0);
- X if (inwin == (WINDOW *) NULL)
- X clean_up();
- X
- X /* print out header */
- X box(inwin, '|', '-');
- X for (n = 0; n < 4; n++)
- X mvwaddstr(inwin, n + 1, COLS / 2 - strlen(header[n]) / 2, header[n]);
- X mvwaddstr(inwin, 6, 15, "Enter input --> ");
- X /* get the prompt positions so we can return at later time */
- X getyx(inwin, y_pos, x_pos);
- X wrefresh(inwin);
- X
- X /* now get string */
- X do
- X {
- X /* clear last input */
- X wmove(inwin, y_pos, x_pos);
- X wclrtoeol(inwin);
- X box(inwin, '|', '-');
- X wrefresh(inwin);
- X
- X /*
- X * get string. NO_RET=0 and RET=1 are defined in
- X * "my_wgetstr.h"
- X */
- X n = my_wgetstr(inwin, buffer, sizeof(buffer), NO_RET);
- X
- X /* print out the result of my_wgetstr */
- X move(15, 15);
- X clrtoeol();
- X mvprintw(15, 15, "Received %d chars -- \"%s\"", n, buffer);
- X refresh();
- X
- X /* move back to the input prompt */
- X wmove(inwin, y_pos, x_pos);
- X wrefresh(inwin);
- X }
- X while (n != 0); /* while input is not empty */
- X
- X name = getenv("NAME");
- X if (name == (char *) NULL) /* use login if NAME is not set */
- X name = getlogin();
- X /* say good bye */
- X move(15, 15);
- X clrtoeol();
- X sprintf(ender, "GOOD BYE, \"%s\"", name);
- X mvprintw(15, COLS / 2 - strlen(ender) / 2, "%s", ender);
- X
- X /* move to last line ... looks cleaner this way */
- X move(LINES - 1, 0);
- X refresh();
- X clean_up();
- X}
- X
- Xclean_up()
- X{
- X endwin();
- X exit();
- X}
- SHAR_EOF
- if test 2271 -ne "`wc -c < 'example.c'`"
- then
- echo shar: error transmitting "'example.c'" '(should have been 2271 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'makefile'" '(128 characters)'
- if test -f 'makefile'
- then
- echo shar: will not over-write existing file "'makefile'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'makefile'
- XLIBS= -lcurses -ltermcap
- XOBJS= example.o my_wgetstr.o
- XCFLAGS= -s -O
- X
- Xexample: $(OBJS)
- X cc $(CFLAGS) -o example $(OBJS) $(LIBS)
- SHAR_EOF
- if test 128 -ne "`wc -c < 'makefile'`"
- then
- echo shar: error transmitting "'makefile'" '(should have been 128 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'my_wgetstr.c'" '(3993 characters)'
- if test -f 'my_wgetstr.c'
- then
- echo shar: will not over-write existing file "'my_wgetstr.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'my_wgetstr.c'
- X/*
- X * A possible replacement for curses' wgetstr(). Allows
- X * line editing as in csh.
- X * Recognizes the erase, kill chars, word deleting.
- X *
- X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott)
- X * History:
- X * 01/18/89 - Initial version
- X * 03/20/89 - Add control-w to delete word
- X * 05/17/89 - add option to return immediately or to bell()
- X * when buffer is full.
- X *
- X * Release to Public Domain
- X */
- X#include <curses.h>
- X#include <sys/ioctl.h>
- X#include <sgtty.h>
- X
- X#define STD_INPUT 0 /* standard input */
- X#define NEWLINE '\n'
- X#define SPACE ' '
- X/* default for erase and kill characters */
- X#define ERASE '\010'
- X#define KILL '\025'
- X#define WORD '\027'
- X
- X/* You bugger !!! you did something wrong */
- X#define bell() fprintf(stderr,"%c", '\007')
- X
- X/*
- X * my_wgetstr(WINDOW *win, char *str, int size, int ret)
- X * win: the concerned window
- X * str: buffer holding input
- X * size: (size -1) is the maximum chars to get
- X * ret: flag indicating what to do when (size -1) is reached
- X * 0: ring bell()
- X * 1: returns
- X * two macros are defined in "my_wgetstr.h" as RET=1 and NO_RET=0
- X *
- X * works same as wgetstr() in curses but allows editing.
- X * Recognizes the erase character and the kill character and
- X * WORD as the word deleting char.
- X * Will try to get the erase and kill char from the terminal setting.
- X * If failed, will use the default ERASE and KILL definitions.
- X * Word char is set to WORD.
- X *
- X * DOES NOT check for illegal scrolling.
- X * Returns
- X * . when received a new line character
- X * . if ( (strlen(str) == (size - 1)) and (ret) )
- X *
- X * str[size - 1] must be set to '\0' to end the string properly
- X * so my_wgetstr(errwin, str, 8) will get at most 7 characters.
- X *
- X * Returned value is the number of chars read.
- X */
- X
- Xmy_wgetstr(win, str, size, ret)
- XWINDOW *win;
- Xchar *str;
- Xint size;
- Xint ret;
- X{
- X struct sgttyb ttyb;
- X char erase_char, kill_char;
- X register int x_pos, y_pos, index, in;
- X
- X if (ioctl(STD_INPUT, TIOCGETP, &ttyb) == -1)
- X {
- X /*
- X * failed to get terminal setting. Let's use the default
- X * ERASE and KILL
- X */
- X erase_char = ERASE;
- X kill_char = KILL;
- X }
- X else
- X {
- X erase_char = ttyb.sg_erase;
- X kill_char = ttyb.sg_kill;
- X }
- X
- X /*
- X * since we are going to set noecho() and crmode() let's be safe and
- X * save the current tty
- X */
- X savetty();
- X noecho();
- X crmode();
- X
- X /* get current position */
- X getyx(win, y_pos, x_pos);
- X /* intializing */
- X index = 0;
- X str[index] = '\0';
- X
- X /* while input char is not NEWLINE */
- X while ((in = getch() & 0177) != NEWLINE)
- X {
- X /* if buffer is full (size -1) */
- X if (index >= size - 1)
- X if (ret)/* return flag set, return immediately */
- X break;
- X else /* allows editing chars to pass through */
- X if ((in != erase_char) && (in != kill_char) && (in != WORD))
- X {
- X /* warns user that buffer is full */
- X bell();
- X continue;
- X }
- X
- X if (in == erase_char) /* ERASING */
- X {
- X if (index > 0)
- X {
- X mvwaddch(win, y_pos, --x_pos, SPACE);
- X str[--index] = SPACE;
- X wmove(win, y_pos, x_pos);
- X }
- X else
- X bell();
- X }
- X else
- X if (in == kill_char) /* KILLING */
- X {
- X if (index > 0)
- X while (index > 0)
- X {
- X mvwaddch(win, y_pos, --x_pos, SPACE);
- X str[--index] = SPACE;
- X wmove(win, y_pos, x_pos);
- X }
- X else
- X bell();
- X }
- X else
- X if (in == WORD) /* WORD DELETING */
- X {
- X if (index > 0)
- X {
- X /* throw away all spaces */
- X while ((index > 0) && (str[index - 1] == SPACE))
- X {
- X mvwaddch(win, y_pos, --x_pos, SPACE);
- X str[--index] = SPACE;
- X wmove(win, y_pos, x_pos);
- X }
- X /* move back until see another space */
- X while ((index > 0) && (str[index - 1] != SPACE))
- X {
- X mvwaddch(win, y_pos, --x_pos, SPACE);
- X str[--index] = SPACE;
- X wmove(win, y_pos, x_pos);
- X }
- X }
- X else
- X bell();
- X }
- X else
- X {
- X mvwaddch(win, y_pos, x_pos++, in);
- X str[index++] = in;
- X }
- X /* show result */
- X wrefresh(win);
- X }
- X /* ends the string properly */
- X str[index] = '\0';
- X /* restore the tty */
- X resetty();
- X /* returns number of chars read */
- X return (index);
- X}
- SHAR_EOF
- if test 3993 -ne "`wc -c < 'my_wgetstr.c'`"
- then
- echo shar: error transmitting "'my_wgetstr.c'" '(should have been 3993 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'my_wgetstr.h'" '(400 characters)'
- if test -f 'my_wgetstr.h'
- then
- echo shar: will not over-write existing file "'my_wgetstr.h'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'my_wgetstr.h'
- X/*
- X * A possible replacement for curses' wgetstr(). Allows
- X * limited editing. Recognizes the erase and kill chars.
- X *
- X * By Hung Le (mott@ucscb.ucsc.edu ...!ucbvax!ucscc!ucscb!mott)
- X * History:
- X * 05/18/89 - Initial version
- X *
- X * Release to Public Domain
- X */
- X
- X/* following the curses's convention */
- X#define my_getstr(str,size,ret) my_wgetstr(stdscr,str,size,ret)
- X#define RET 1
- X#define NO_RET 0
- X
- SHAR_EOF
- if test 400 -ne "`wc -c < 'my_wgetstr.h'`"
- then
- echo shar: error transmitting "'my_wgetstr.h'" '(should have been 400 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-
-